﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Physis.Data {

    public class DatabaseConfiguration {

        #region Private Properties

        private Enumerations.DatabaseType databaseType = Enumerations.DatabaseType.MicrosoftSqlServer;


        private String serverName = "(local)";

        private String databaseName = String.Empty;


        private Boolean poolingEnabled = false;

        private Int32 poolSizeMinimum = 1;

        private Int32 poolSizeMaximum = 10;


        private Boolean trustedConnection = true;

        private String userName = String.Empty;

        private String password = String.Empty;

        private String customAttributes = String.Empty;

        #endregion


        #region Public Properties

        public Enumerations.DatabaseType DatabaseType { get { return databaseType; } set { databaseType = value; } }

        public String ServerName { get { return serverName; } set { serverName = value; } }

        public String DatabaseName { get { return databaseName; } set { databaseName = value; } }

        public Boolean PoolingEnabled { get { return poolingEnabled; } set { poolingEnabled = value; } }

        public Int32 PoolSizeMinimum {

            get { return poolSizeMinimum; }

            set { 
                
                poolSizeMinimum = Math.Max (1, value); // POOL SIZE MUST BE AT LEAST 1

                // MAKE SURE MAXIMUM IS MORE THAN MINIMUM

                if (poolSizeMaximum < poolSizeMinimum) { 

                    poolSizeMaximum = poolSizeMinimum; // RESET MAXIMUM TO THE MINIMUM

                }
            
            }

        }

        public Int32 PoolSizeMaximum {

            get { return poolSizeMaximum; }

            set { poolSizeMaximum = Math.Max (poolSizeMinimum, value); } // MAKE SURE THAT MAXIMUM IS AT LEAST MINIMUM 

        }

        public Boolean TrustedConnection { get { return trustedConnection; } set { trustedConnection = value; } }

        public String UserName { get { return userName; } set { userName = value; } }

        public String Password { get { return password; } set { password = value; } }

        public String CustomAttributes { get { return customAttributes; } set { customAttributes = value; } }

        #endregion


        #region Constructors

        public DatabaseConfiguration () { /* DO NOTHING */ }

        public DatabaseConfiguration (String configurationPrefix) {

            ReadFromAppSettings (configurationPrefix);

            return;

        }

        #endregion


        #region Set Configuration Properties

        public void ReadFromAppSettings (String configurationPrefix) {

            try {

                try {

                    DatabaseType = (Enumerations.DatabaseType)Enum.Parse (typeof (Enumerations.DatabaseType), System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".DatabaseType")[0].ToString ());

                }

                catch {

                    DatabaseType = Enumerations.DatabaseType.MicrosoftSqlServer;

                }

                ServerName = System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".ServerName")[0].ToString ();

                DatabaseName = System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".DatabaseName")[0].ToString ();

                try {

                    PoolingEnabled = Convert.ToBoolean (System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".PoolingEnabled")[0].ToString ());

                    if (poolingEnabled) {

                        PoolSizeMinimum = Convert.ToInt32 (System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".PoolSizeMinimum")[0].ToString ());

                        PoolSizeMaximum = Convert.ToInt32 (System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".PoolSizeMaximum")[0].ToString ());

                    }

                }

                catch {

                    PoolingEnabled = false;

                }

                try {

                    TrustedConnection = Convert.ToBoolean (System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".TrustedConnection")[0].ToString ());

                }

                catch {

                    TrustedConnection = true;

                }

                if (!trustedConnection) {

                    try {

                        UserName = System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".UserName")[0].ToString ();

                        Password = System.Configuration.ConfigurationManager.AppSettings.GetValues (configurationPrefix + ".Password")[0].ToString ();
                    }

                    catch {
                        // DO NOTHING

                    }

                }

            } // end try

            catch (Exception ConfigException) {

                throw (new ApplicationException ("Unable to read Database Configuration Settings.", ConfigException));

            } // end catch 

            return;

        }

        public void SetConfiguration (String serverName, String databaseName, Boolean poolingEnabled, Int32 poolSizeMinimum, Int32 poolSizeMaximum, String customAttributes = "") {

            ServerName = serverName;

            DatabaseName = databaseName;

            PoolingEnabled = poolingEnabled;

            PoolSizeMinimum = poolSizeMinimum;

            PoolSizeMaximum = poolSizeMaximum;

            CustomAttributes = customAttributes;

            return;

        }

        public void SetCredentials (String userName, String password) {

            trustedConnection = false;

            UserName = userName;

            Password = password;

            return;

        }

        #endregion


    }

}
